﻿using MS_Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MS_UI
{
    public class CommThread
    {
        public Thread t;
        public CommThread()
        {
            t = new Thread(Communication);
            t.IsBackground = true;
        }

        // 起始地址
        int StartAddress = 0;
        // 错误次数
        int ErrorTimer = 0;
        // 0x区域的变量列表
        public List<Variable_Modbus> List_0x = new List<Variable_Modbus>();
        // 1x区域的变量列表
        public List<Variable_Modbus> List_1x = new List<Variable_Modbus>();
        // 3x区域的变量列表
        public List<Variable_Modbus> List_3x = new List<Variable_Modbus>();
        // 4x区域的变量列表
        public List<Variable_Modbus> List_4x = new List<Variable_Modbus>();

        #region 实时通讯
        /// <summary>
        /// 实时通讯
        /// </summary>
        private void Communication()
        {
            // 实时通讯
            while (true)
            {
                if (CommonMethod.IsWriting == false)
                {
                    foreach (StoreArea item in CommonMethod.StoreAreaList)
                    {
                        int timer = 0;
                        List<byte> ByteList = null;
                        switch (item.StoreType)
                        {
                            case "01 Coli Status(0x)":
                                ByteList = new List<byte>();
                                // 如果长度过大，分批次去读
                                if (item.Length > 100)
                                {
                                    StartAddress = item.StartReg;
                                    timer = item.Length / 100;
                                    for (int i = 0; i <= timer; i++)
                                    {
                                        int readLength = i == timer ? item.Length - 100 * i : 100;
                                        byte[] Res = CommonMethod.objMod.ReadOutputStatus(CommonMethod.Address,StartAddress + 100 * i,readLength);
                                        if (Res != null)
                                        {
                                            ErrorTimer = 0;
                                            ByteList.AddRange(Res);
                                        }
                                        else
                                        {
                                            ErrorTimer += 1;
                                        }
                                    }
                                }
                                else
                                {
                                    byte[] Res = CommonMethod.objMod.ReadOutputStatus(CommonMethod.Address,StartAddress,item.Length);
                                    if (Res != null)
                                    {
                                        ErrorTimer = 0;
                                        ByteList.AddRange(Res);
                                    }
                                    else
                                    {
                                        ErrorTimer += 1;
                                    }
                                }
                                // 解析
                                int length = item.Length % 8 == 0 ? item.Length / 8 : item.Length / 8 + 1;
                                if (ByteList .Count == length)
                                {
                                    AnalyseData_Ox(ByteList);
                                }
                                break;
                            case "03 Holding Register(4x)":
                                ByteList = new List<byte>();
                                // 如果长度过大，分批次去读
                                if (item.Length > 100)
                                {
                                    StartAddress = item.StartReg;
                                    timer = item.Length / 100;
                                    for (int i = 0; i <= timer; i++)
                                    {
                                        int readLength = i == timer ? item.Length - 100 * i : 100;
                                        byte[] Res = CommonMethod.objMod.ReadKeepReg(CommonMethod.Address, StartAddress + 100 * i, readLength);
                                        if (Res != null)
                                        {
                                            ErrorTimer = 0;
                                            ByteList.AddRange(Res);
                                        }
                                        else
                                        {
                                            ErrorTimer += 1;
                                        }
                                    }
                                }
                                else
                                {
                                    byte[] Res = CommonMethod.objMod.ReadKeepReg(CommonMethod.Address, StartAddress, item.Length);
                                    if (Res != null)
                                    {
                                        ErrorTimer = 0;
                                        ByteList.AddRange(Res);
                                    }
                                    else
                                    {
                                        ErrorTimer += 1;
                                    }
                                }
                                // 解析
                                if (ByteList.Count == item.Length * 2)
                                {
                                    AnalyseData_4x(ByteList);
                                }
                                break;
                            default:
                                break;
                        }
                    }
                }
            }
        }
        #endregion

        #region 解析数据
        /// <summary>
        /// 解析0x区域
        /// </summary>
        /// <param name="ByteList"></param>
        private void AnalyseData_Ox(List<byte> ByteList)
        {
            if (ByteList != null && ByteList.Count > 0)
            {
                foreach (Variable_Modbus item in this.List_0x)
                {
                    int totalIndex = int.Parse(item.Address) - StartAddress ;
                    int ByteIndex = totalIndex / 8;
                    int Bitindex = totalIndex % 8;
                    switch (item.DataType)
                    {
                        case "Bool":
                            string ByteStr = Convert.ToInt32(Convert.ToString(Convert.ToInt32(ByteList[ByteIndex]), 2)).ToString("0#######");
                            CommonMethod.CurrentValue[item.VarName] = ByteStr.Substring(7-Bitindex,1);
                            break;
                        default:
                            break;
                    }




                }
            }
        }

        /// <summary>
        /// 解析4x区域
        /// </summary>
        /// <param name="ByteList"></param>
        private void AnalyseData_4x(List<byte> ByteList )
        {
            int StartByte;
            byte[] Res = null;
            if (ByteList != null && ByteList.Count > 0)
            {
                foreach (Variable_Modbus item in this.List_4x)
                {
                    switch (item.DataType)
                    {
                        case "Float":
                            StartByte = int.Parse(item.Address) * 2 ;
                            Res = new byte[4] { ByteList[StartByte] , ByteList[StartByte+1] , ByteList[StartByte+2] , ByteList[StartByte+3] };
                            CommonMethod.CurrentValue[item.VarName] = Convert.ToDouble(MS_Entity.Double.BytetoFloatByPoint(Res)).ToString("f1");
                            break;
                        case "Unsigned":
                            StartByte = int.Parse(item.Address) * 2;
                            Res = new byte[2] { ByteList[StartByte], ByteList[StartByte + 1]};
                            CommonMethod.CurrentValue[item.VarName] = MS_Entity.Int.FromByteArray(Res).ToString();
                            break;
                        default:
                            break;
                    }
                }
            }
        }

        #endregion

    }
}
